package com.yu.waterstation.app.moudles.worker.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yu.waterstation.common.entity.app.form.UpdatePasswordByWeiXinForm;
import com.yu.waterstation.common.entity.app.form.UpdatePasswordForm;
import com.yu.waterstation.common.entity.app.form.WeixinLoginForm;
import com.yu.waterstation.app.moudles.worker.mapper.WorkerMapper;
import com.yu.waterstation.common.entity.app.Worker;
import com.yu.waterstation.common.entity.app.dto.WorkerDTO;
import com.yu.waterstation.common.entity.app.form.UpdateWorkerForm;
import com.yu.waterstation.common.entity.app.form.WorkerLoginForm;
import com.yu.waterstation.common.common.config.property.WeixinProperty;
import com.yu.waterstation.common.common.exception.ServiceException;
import com.yu.waterstation.common.common.util.GeneratorUtil;
import com.yu.waterstation.common.common.util.http.HttpUtil;
import com.yu.waterstation.common.common.util.result.Result;

import com.yu.waterstation.common.service.RedisService;
import com.yu.waterstation.app.common.util.session.SessionUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

@Slf4j
@Service
public class WorkerServiceImpl implements WorkerService {
    @Resource
    private WorkerMapper workerMapper;

    @Resource
    private WeixinProperty wxProperty;

    @Resource
    private RedisService redisService;

    @Transactional
    @Override
    public Result<WorkerDTO> login(WorkerLoginForm loginVo) throws Exception {
        Worker worker = workerMapper.selectOne(new QueryWrapper<Worker>()
                .eq("phone", loginVo.getPhone()));
        if (worker == null)
            return Result.fail("账号不存在");
        if (!worker.getPassword().equals(GeneratorUtil.md5Base64(loginVo.getPassword())))
            return Result.fail("密码错误");
        if (!worker.getStatus())
            return Result.fail("账号已被冻结");

        WorkerDTO workerDTO = getWorkerInfo(worker.getId());
        SessionUtil.setWorkerSession(workerDTO);
        return Result.ok(workerDTO);
    }

    @Transactional
    @Override
    public  Result<WorkerDTO>  loginByWx(WeixinLoginForm loginForm)   {
        String openid = getWeiXinOpenid(loginForm.getWxCode());
        if (openid != null) {
            Worker worker = workerMapper.selectOne(new QueryWrapper<Worker>().eq("wx_openid", openid));
            if (worker == null)
                return Result.fail("账号不存在");
            if (!worker.getStatus())
                return Result.fail("账号已被冻结");

            worker.setWxAvatar(loginForm.getWxAvatar());
            workerMapper.updateById(worker); // 更新微信头像
            WorkerDTO workerDTO = getWorkerInfo(worker.getId());
            SessionUtil.setWorkerSession(workerDTO);
            return Result.ok(workerDTO);
        } else {
            return Result.fail("微信登录失败");
        }
    }

    /**
     * 根据code获取微信openid
     *
     * @param code
     * @return
     */
    private String getWeiXinOpenid(String code) {
        String urlStr = "https://api.weixin.qq.com/sns/jscode2session?appid=" + wxProperty.getAppid()
                + "&secret=" + wxProperty.getAppSecret()
                + "&grant_type=authorization_code&js_code=" + code;
        String html = HttpUtil.getHtml(urlStr);
        JSONObject result = JSON.parseObject(html);
        Integer errcode = result.getInteger("errcode");
        if (errcode == null || errcode.equals(0))
            return result.getString("openid");
        else {
            log.error("[获取openid失败] 回复报文:{}", html);
            return null;
        }
    }

    // 送水员详细信息
    @Override
    public WorkerDTO getWorkerInfo(Integer workerId) {
        Worker worker = workerMapper.selectById(workerId);
        if (worker == null)
            return null;

        WorkerDTO workerDTO = new WorkerDTO();
        workerDTO.setId(workerId);
        BeanUtils.copyProperties(worker, workerDTO);
        return workerDTO;
    }


    // 绑定微信
    @Transactional(rollbackFor = Exception.class)
    @Override
    public String bindWeiXin(Integer workerId, WeixinLoginForm form) throws ServiceException {
        String openid = getWeiXinOpenid(form.getWxCode());
        if (openid != null) {
            workerMapper.deleteOpenid(openid); // 先解绑之前的
            Worker worker = new Worker();
            worker.setId(workerId);
            worker.setWxOpenid(openid);
            worker.setWxAvatar(form.getWxAvatar());
            workerMapper.updateById(worker);
            return openid;
        } else {
            throw ServiceException.CONST_bind_wei_xin_failed;
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int updatePassword(Integer workerId, UpdatePasswordForm vo) throws Exception {
        if (StringUtils.isEmpty(vo.getOldPassword()) || StringUtils.isEmpty(vo.getNewPassword())
                || vo.getNewPassword().length() < 6 || vo.getNewPassword().length() > 18)
            throw ServiceException.CONST_password_not_validate;

        if (vo.getOldPassword().equals(vo.getNewPassword()))
            throw ServiceException.CONST_new_password_can_not_equals_old_password; // 新旧密码相同

        Worker worker = workerMapper.selectById(workerId);
        if (!GeneratorUtil.md5Base64(vo.getOldPassword()).equals(worker.getPassword()))
            throw ServiceException.CONST_old_password_error;

        worker.setPassword(GeneratorUtil.md5Base64(vo.getNewPassword()));
        return workerMapper.updateById(worker);
    }

    // 微信授权修改密码
    @Transactional
    @Override
    public int updatePasswordByWeiXin(Integer workerId, UpdatePasswordByWeiXinForm vo) throws Exception {
        String openid = getWeiXinOpenid(vo.getWxCode());
        System.out.println(vo);
        if (openid == null)
            throw ServiceException.CONST_get_weixin_openid_failed; // 获取openid失败

        if (StringUtils.isEmpty(vo.getNewPassword())
                || vo.getNewPassword().length() < 6 || vo.getNewPassword().length() > 18)
            throw ServiceException.CONST_password_not_validate;

        Worker worker = workerMapper.selectById(workerId);
        if (vo.getNewPassword().equals(worker.getPassword()))
            throw ServiceException.CONST_new_password_can_not_equals_old_password;

        if (worker.getWxOpenid() == null)
            throw ServiceException.CONST_user_not_bind_wei_xin;

        if (!openid.equals(worker.getWxOpenid())) { // 验证openid
            log.error("[账号绑定的openid[{}] 验证的openid[{}]", worker.getWxOpenid(), openid);
            throw ServiceException.CONST_wx_validate_failed;
        }

        worker.setPassword(GeneratorUtil.md5Base64(vo.getNewPassword()));
        return workerMapper.updateById(worker);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public WorkerDTO updateWorkerInfo(Integer workerId, UpdateWorkerForm vo) throws Exception {
        Worker worker = new Worker();
        worker.setId(workerId);
        worker.setName(vo.getName());
        worker.setSex(vo.getSex());
        worker.setWxAvatar(vo.getWxAvatar());
        workerMapper.updateById(worker);
        return getWorkerInfo(workerId);
    }
}
